<?php

namespace App\Http\Services;

use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use App\Http\Model\Hint;
use App\Http\Model\User;
use App\Http\Model\RedPacketRain;
use App\Http\Model\FinanceUserWallet;
use App\Http\Model\FinanceDiamond;
use App\Http\Model\System;
use App\Http\Model\FinanceRechargeOrder;
use App\Http\Model\Union;
use App\Http\Model\Room;
use App\Http\Services\MsgServices;


class RedPacketRainServices extends CommonServices
{
    protected $userModel;
    protected $userWalletModel;
    protected $financeDiamondModel;
    protected $redPacketRainModel;
    protected $msgService;
    protected $finance_service;
    protected $systemModel;
    protected $financeRechargeModel;
    protected $unionModel;
    protected $roomModel;

    public function __construct()
    {
        parent::__construct();

        $this->userModel = new User();
        $this->userWalletModel = new FinanceUserWallet();
        $this->financeDiamondModel = new FinanceDiamond();
        $this->redPacketRainModel = new RedPacketRain();
        $this->msgService = new MsgServices();
        $this->finance_service = new FinanceServices();
        $this->systemModel = new System();
        $this->financeRechargeModel = new FinanceRechargeOrder();
        $this->unionModel = new Union();
        $this->roomModel = new Room();
    }

    /**
     * 红包雨新增
     */
    public function redPacketRainAdd($startTime, $rechargeDiamondNum, $allDiamondNum, $packetNum, $minNum, $maxNum, $adminId){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();
        do {
            if(empty($startTime) || empty($allDiamondNum) || empty($packetNum) || empty($minNum) || empty($maxNum) || empty($adminId)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            if(strtotime($startTime) < ($now+3600)) {
                $code = Hint::PARAM_ERROR;
                $msg = '红包雨需要提前一小时配置';
                break;
            }
            //两场相近的红包雨间隔时间，至少超过60分钟
            $timeSt = date("Y-m-d H:i:s", strtotime($startTime)-3600);
            $timeEd = date("Y-m-d H:i:s", strtotime($startTime)+3600);
            $info = $this->redPacketRainModel->getRedPacketRainByTime($timeSt, $timeEd);
            if(!empty($info)) {
                $code = Hint::PARAM_ERROR;
                $msg = '两场相近的红包雨间隔时间，至少超过60分钟';
                break;
            }

            if($allDiamondNum < ($packetNum*$maxNum)) {
                $code = Hint::PARAM_ERROR;
                $msg = '总钻石数不足无法发放';
                break;
            }

            //新增
            $id = $this->redPacketRainModel->addRedPacketRain($startTime, $rechargeDiamondNum, $allDiamondNum, $packetNum, $minNum, $maxNum, $adminId);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 红包雨编辑
     */
    public function redPacketRainEdit($rainId, $startTime, $rechargeDiamondNum, $allDiamondNum, $packetNum, $minNum, $maxNum, $adminId){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();
        do {
            if(empty($rainId)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $info = $this->redPacketRainModel->getRedPacketRainById($rainId);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
           
  	       if(strtotime($info['start_time']) < ($now+3600)) {
                $code = Hint::PARAM_ERROR;
                $msg = '红包雨开始前一小时不可修改';
                break;
            }
            if(!empty($startTime)) {
                if(strtotime($startTime) < ($now+3600)) {
                    $code = Hint::PARAM_ERROR;
                    $msg = '红包雨需要提前一小时配置';
                    break;
                }
                //两场相近的红包雨间隔时间，至少超过60分钟
                $timeSt = date("Y-m-d H:i:s", strtotime($startTime)-3600);
                $timeEd = date("Y-m-d H:i:s", strtotime($startTime)+3600);
                $info = $this->redPacketRainModel->getRedPacketRainByTime($timeSt, $timeEd, $rainId);
                if(!empty($info)) {
                    $code = Hint::PARAM_ERROR;
                    $msg = '两场相近的红包雨间隔时间，至少超过60分钟';
                    break;
                }
            }
            if(!empty($allDiamondNum)) {
                $info['all_diamond_num'] = $allDiamondNum;
            }
            if(!empty($packetNum)) {
                $info['packet_num'] = $packetNum;
            }
            if(!empty($maxNum)) {
                $info['max_num'] = $maxNum;
            }

            if($info['all_diamond_num'] < ($info['packet_num']*$info['max_num'])) {
                $code = Hint::PARAM_ERROR;
                $msg = '总钻石数不足无法发放';
                break;
            }

            //更新
            $this->redPacketRainModel->editRedPacketRain($rainId, ['start_time'=>$startTime, 'recharge_diamond_num'=>$rechargeDiamondNum, 'all_diamond_num'=>$allDiamondNum, 'packet_num'=>$packetNum, 'min_num'=>$minNum, 'max_num'=>$maxNum, 'admin_id'=>$adminId]);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 红包雨删除
     */
    public function redPacketRainDel($rainId, $adminId){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();
        do {
            if(empty($rainId)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $info = $this->redPacketRainModel->getRedPacketRainById($rainId);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            if(strtotime($info['start_time']) < ($now+3600)) {
                $code = Hint::PARAM_ERROR;
                $msg = '红包雨开始前一小时不可修改';
                break;
            }

            //更新
            $this->redPacketRainModel->editRedPacketRain($rainId, ['is_delete'=>1, 'admin_id'=>$adminId]);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 每分钟检查是否有即将开始的红包雨并发消息
     */
    public function redPacketRainCheck(){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();
        do {
            //半小时内
            $timeSt = date("Y-m-d H:i:s", $now);
            $timeEd = date("Y-m-d H:i:s", $now+1800);
            $info = $this->redPacketRainModel->getRedPacketRainByTime($timeSt, $timeEd);
            if(empty($info)) {
                break;
            }
            $rainId = $info['id'];
            //缓存生成
            $res = $this->redPacketRainModel->checkRedPacketRainPoolHas($rainId);
            if($res != 1) {
                $lockKey = 'REDPACKETRAIN:makeRedPacketRainPool:'.$rainId;
                if (redis_lock($lockKey, 180)){
                    $res = $this->redPacketRainModel->makeRedPacketRainPool($rainId);

                    redis_unlock($lockKey);
                }
            }

            //活动开始前五分钟发信息
            $fiveMinute = strtotime($info['start_time']) - 300;
            if($now >= $fiveMinute) {
                //检查缓存是否生成了
                $res = $this->redPacketRainModel->checkRedPacketRainPoolHas($rainId);
                if($res == 1) {
                    //红包雨即将开始全员通知
                    $data = [];
                    $data['status'] = 1;
                    $data['rain_id'] = $info['id'];
                    $data['start_time'] = strtotime($info['start_time']);
                    $data['limit_second'] = $info['limit_second'];
                    $data['recharge_diamond_num'] = $info['recharge_diamond_num'];
                    $this->msgService->redPacketRainMsg($data);
                }
            }

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 每分钟检查是否活动结束发系统信息
     */
    public function redPacketRainCheckSendMsg(){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();
        do {
            //一分钟内
            $timeSt = date("Y-m-d H:i:s", $now-120);
            $timeEd = date("Y-m-d H:i:s", $now);
            $info = $this->redPacketRainModel->getRedPacketRainByTime($timeSt, $timeEd);
            if(empty($info)) {
                break;
            }
            $overTime = strtotime($info['start_time']) + $info['limit_second'];
            if($now <= $overTime) {
                break;
            }
            $rainId = $info['id'];
            $lockKey = 'REDPACKETRAIN:redPacketRainCheckSendMsg:'.$rainId;
            if (redis_lock($lockKey, 300)){
                //获取抢到了的用户
                $list = $this->redPacketRainModel->getRedPacketRainLogList($rainId);
                foreach($list as $val) {
                    $msg = '恭喜您，在此次红包雨获得了'.$val['diamond_num'].'钻';
                    $this->msgService->send_sys_text_msg($val['user_id'], $msg);
                }
            }

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 红包雨获取即将开始的一场数据
     */
    public function redPacketRainGetNewly($userId, $roomId){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();
        do {
            $data['status'] = 0;//是否存在 0=否 1=是

            //CBD房间
            if(empty($roomId)) {
                break;
            }

            $roomInfo = $this->roomModel->getRoomTypeByRoomId($roomId);

            if($roomInfo['business_type'] != 1) {
                break;//非BCD房间
            }

            //半小时内
            $timeSt = date("Y-m-d H:i:s", $now);
            $timeEd = date("Y-m-d H:i:s", $now+1800);

            $info = $this->redPacketRainModel->getRedPacketRainByTime($timeSt, $timeEd);

            if(empty($info)) {
                break;
            }
            //检查缓存是否生成了
            $res = $this->redPacketRainModel->checkRedPacketRainPoolHas($info['id']);

            if($res != 1) {
                break;
            }

            //用户充值
            if($info['recharge_diamond_num'] > 0) {

                $userRechargeDiamond = $this->financeRechargeModel->getRechargeDiamondTotal($userId);

                if($userRechargeDiamond < $info['recharge_diamond_num']) {
                    break;
                }
            }

            $data['status'] = 1;
            $data['rain_id'] = $info['id'];
            $data['start_time'] = strtotime($info['start_time']);
            $data['limit_second'] = $info['limit_second'];
            $data['recharge_diamond_num'] = $info['recharge_diamond_num'];

        } while (false);
        $data['now'] = time();

        return compact('code', 'msg', 'data');
    }

    /**
     * 红包雨抢红包
     */
    public function redPacketRainDraw($userId, $roomId, $rainId){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();
        $diamondNum = 0;
        do {
            if(empty($roomId) || empty($rainId)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $roomInfo = $this->roomModel->getRoomById($roomId);
            if($roomInfo['business_type'] != 1) {
                break;//非BCD房间
            }
            //根据id获取红包雨
            $info = $this->redPacketRainModel->getRedPacketRainById($rainId);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            //是否已结束
            $endTime = strtotime($info['start_time']) + $info['limit_second'] - 1;
            if($now < strtotime($info['start_time'])) {
                break;
            }
            if($now > $endTime) {
                break;
            }
            //用户是否参与过了
            $diamondNumOld = $this->redPacketRainModel->checkUserRedPacketRain($rainId, $userId);
            if($diamondNumOld > 0) {
                $diamondNum = $diamondNumOld;
                break;
            }
            //用户充值
            if($info['recharge_diamond_num'] > 0) {
                $userRechargeDiamond = $this->financeRechargeModel->getRechargeDiamondTotal($userId);
                if($userRechargeDiamond < $info['recharge_diamond_num']) {
                    break;
                }
            }

            try {
                $startTime = date('YmdHis', strtotime($info['start_time']));
                $limitSecond = $info['limit_second'];//持续秒数
                //获取一个
                $diamondNum = $this->redPacketRainModel->drawRedPacketRain($userId, $info, $now);
                //抢到了
                if($diamondNum > 0) {
                    //获取用户公会
                    $userUnion = $this->unionModel->getUserUnionInfo($userId);

                    //房间公会
                    $roomUnion = $this->unionModel->getUnionByRoomId($roomId);

                    $config = config('pay');
                    $diamond_desc = $config['wallet_change_desc']['diamond_red_packet_rain_out'];

                    $log = [
                        'user_id' => $userId,
                        'rain_id' => $rainId,
                        'diamond_num' => $diamondNum,
                        'user_union_id' => empty($userUnion['id']) ? 0 : $userUnion['id'],
                        'user_union_name' => empty($userUnion['name']) ? '' : $userUnion['name'],
                        'room_id' => $roomId,
                        'room_name' => $roomInfo['name'],
                        'room_union_id' => empty($roomUnion['id']) ? 0 : $roomUnion['id'],
                        'room_union_name' => empty($roomUnion['name']) ? '' : $roomUnion['name'],
                    ];
                    $this->redPacketRainModel->addRedPacketRainLog($log);

                    $this->financeDiamondModel->inc($userId, 0, $roomId, 88, $diamondNum, $diamond_desc);
                }
            } catch (\Exception $e) {
                $code = Hint::ERR_SYS_FAIL;
                write_log('error_redPacketRain', 'redPacketRainDraw 失败', ['userId'=>$userId, 'roomId'=>$roomId, 'rainId'=>$rainId, 'message'=>$e->getMessage(), 'line'=>$e->getLine()]);
                break;
            }

        } while (false);
        $data['diamond_num'] = $diamondNum;

        return compact('code', 'msg', 'data');
    }


}
